from django.shortcuts import render
from rest_framework import serializers
from rest_framework.authentication import TokenAuthentication
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import exceptions
from api import models
from api.models import Blog
import uuid

from ext.hook import JKSerializer
from auth import BlogAuthentication, NoAuthentication


class BlogUserSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.UserInfo
        fields = ["id","username"]
class BlogViewSerializers(JKSerializer,serializers.ModelSerializer):
    class Meta:
        model = models.Blog
        fields = ['id','category','image','title','summary','text','ctime','creator','comment_count','favor_count']
        extra_kwargs = {
            "comment": {"read_only": True},
            "favor": {"read_only":True},
            "text": {"write_only": True},
        }
    def jk_category(self, obj):
        return obj.get_category_display()

class BlogView(APIView):
    authentication_classes = [BlogAuthentication]
    def get(self, request):
        queryset = Blog.objects.all().order_by('-id')
        max_id = request.query_params.get("max_id")
        if max_id:
            queryset = queryset.first(id__lt=max_id)
        #分页的处理
        from rest_framework.pagination import LimitOffsetPagination
        pager = LimitOffsetPagination()
        result = pager.paginate_queryset(queryset,request,self)
        # total_result = pager.get_paginated_response(self)
        ser = BlogViewSerializers(instance=result, many=True)
        response = pager.get_paginated_response(ser.data)
        return response
    def post(self, request):
        if not request.user:
            return Response({"code":1005,"data":"认证失败"})
        ser = BlogViewSerializers(data=request.data)
        if not ser.is_valid():
            return Response({"code":1006,"data":"校验失败","errors":ser.errors})
        ser.save(creator=request.user)
        return Response({"code":200,"data":ser.data})

class BlogDetailViewSerializer(serializers.ModelSerializer):
    category = serializers.CharField(source="get_category_display")
    ctime = serializers.DateTimeField(format="%Y-%m-%d")
    creator = BlogUserSerializer()
    class Meta:
        model = models.Blog
        fields = "__all__"

class BlogDetailView(APIView):
    def get(self, *args,**kwargs):
        pk = kwargs.get('pk')
        instance = models.Blog.objects.filter(id=pk).first()
        if not instance:
            return Response({"code":1001,"error":"不存在"})
        ser = BlogDetailViewSerializer(instance=instance)
        context = {"code":200,"data":ser.data}
        return Response(context)

class RegisterViewSerializer(serializers.ModelSerializer):
    password_confirm = serializers.CharField(write_only=True)

    class Meta:
        model = models.UserInfo
        fields = ["id","username","password","password_confirm"]
        extra_kwargs = {
            "id":{"read_only":True},
            "password":{"write_only":True}
        }
    def validate_password(self,value):
        return value
    def validate_password_confirm(self,value):
        password = self.initial_data.get("password")
        if password != value:
            raise exceptions.ValidationError("密码不一致")
        return value
class RegisterView(APIView):
    def post(self,request):
        ser = RegisterViewSerializer(data=request.data)
        if ser.is_valid():
            ser.validated_data.pop("password_confirm")
            ser.save()
            return Response({"code":200,"data":ser.data})
        else:
            return Response({"code":1001,"error":ser.errors})
class LoginViewSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.UserInfo
        fields = ["username","password"]
class LoginView(APIView):
    authentication_classes = [BlogAuthentication]
    def post(self,request):
        ser = LoginViewSerializer(data=request.data)
        if not ser.is_valid():
            return Response({"code":1002,"error":"校验失败","detail":ser.errors})
        instance = models.UserInfo.objects.filter(**ser.validated_data).first()
        if not instance:
            return Response({"code":1003,"error":"用户名或密码错误"})
        token = str(uuid.uuid4())
        instance.token = token
        instance.save()
        return Response({"code":200,"token":token})

class CommentSerializer(JKSerializer,serializers.ModelSerializer):
    class Meta:
        model = models.Comment
        fields = ["id","content","user"]
        extra_kwargs = {
            "user": {"read_only": True},
            "id": {"read_only":True}
        }
    def jk_user(self,obj):
        return obj.user.username
class CommentView(APIView):
    authentication_classes = [BlogAuthentication,]
    def get(self,request,blog_id):
        # ser = CommentSerializer(data=request.data,many=True)
        queryset = models.Comment.objects.filter(id=blog_id)
        ser = CommentSerializer(instance=queryset, many=True)
        context = {"code":200,"data":ser.data}
        return Response(context)

    def post(self,request,blog_id):
        if not request.user:
            return Response({"code":1005,"data":"认证失败"})
        instance = models.Comment.objects.filter(id=blog_id).first()
        if not instance:
            return Response({"code":1006,"data":"博客不存在"})

        ser = CommentSerializer(data=request.data)
        if not ser.is_valid():
            return Response({"code":1006,"data":"博客不存在"})

        ser.save(blog=blog_id,user=request.user)
        return Response({"code":200,"data":ser.data})

class FavorViewSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Favor
        fields = ["id","blog"]
class FavorView(APIView):
    authentication_classes = [BlogAuthentication,NoAuthentication]
    def post(self,request):
        ser = FavorViewSerializer(data=request.data)
        if not ser.is_valid():
            return Response({"code":1002,"error":"校验失败","detail":ser.errors})
        exits = models.Favor.objects.filter(user=request.user,**ser.validated_data).exists()
        if exits:
            return Response({"code":1007,"error":"已存在"})

        ser.save(user=request.user)
        return Response({"code":200,"data":ser.data})


















